

<!doctype html>

<html lang="en" data-content_root="../../">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>skidl.geometry &#8212; SKiDL 2.2.0 documentation</title>
    <link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=fa44fd50" />
    <link rel="stylesheet" type="text/css" href="../../_static/bizstyle.css?v=a66e137f" />
    
    <script src="../../_static/documentation_options.js?v=b21de401"></script>
    <script src="../../_static/doctools.js?v=9bcbadda"></script>
    <script src="../../_static/sphinx_highlight.js?v=dc90522c"></script>
    <script src="../../_static/bizstyle.js"></script>
    <link rel="index" title="Index" href="../../genindex.html" />
    <link rel="search" title="Search" href="../../search.html" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <!--[if lt IE 9]>
    <script src="_static/css3-mediaqueries.js"></script>
    <![endif]-->
  </head><body>
    <h1 id="site-title"><a href="../../../../"><img src="../../../../images/slim_banner.png" width="100%"></a></h1>
    
    <div class="related" role="navigation" aria-label="Related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../../genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="../../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="nav-item nav-item-0"><a href="../../index.html">SKiDL 2.2.0 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="../index.html" accesskey="U">Module code</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">skidl.geometry</a></li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body" role="main">
            
  <h1>Source code for skidl.geometry</h1><div class="highlight"><pre>
<span></span><span class="c1"># -*- coding: utf-8 -*-</span>

<span class="c1"># The MIT License (MIT) - Copyright (c) Dave Vandenbout.</span>

<span class="sd">&quot;&quot;&quot;</span>
<span class="sd">Geometric primitives and transformations for SKiDL.</span>

<span class="sd">This module provides classes and functions to handle geometric operations needed for</span>
<span class="sd">positioning and transforming components. It includes support for</span>
<span class="sd">points/vectors, transformation matrices, and unit conversions between millimeters</span>
<span class="sd">and thousandths-of-inch (mils).</span>
<span class="sd">&quot;&quot;&quot;</span>

<span class="kn">from</span> <span class="nn">math</span> <span class="kn">import</span> <span class="n">sqrt</span><span class="p">,</span> <span class="n">sin</span><span class="p">,</span> <span class="n">cos</span><span class="p">,</span> <span class="n">radians</span>
<span class="kn">from</span> <span class="nn">copy</span> <span class="kn">import</span> <span class="n">copy</span>

<span class="kn">from</span> <span class="nn">.utilities</span> <span class="kn">import</span> <span class="n">export_to_all</span>

<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span>
    <span class="s2">&quot;mms_per_mil&quot;</span><span class="p">,</span>
    <span class="s2">&quot;mils_per_mm&quot;</span><span class="p">,</span>
    <span class="s2">&quot;Vector&quot;</span><span class="p">,</span>
    <span class="s2">&quot;tx_rot_0&quot;</span><span class="p">,</span>
    <span class="s2">&quot;tx_rot_90&quot;</span><span class="p">,</span>
    <span class="s2">&quot;tx_rot_180&quot;</span><span class="p">,</span>
    <span class="s2">&quot;tx_rot_270&quot;</span><span class="p">,</span>
    <span class="s2">&quot;tx_flip_x&quot;</span><span class="p">,</span>
    <span class="s2">&quot;tx_flip_y&quot;</span><span class="p">,</span>
<span class="p">]</span>


<span class="c1"># Millimeters/thousandths-of-inch conversion factor.</span>
<span class="n">mils_per_mm</span> <span class="o">=</span> <span class="mf">39.37008</span>
<span class="n">mms_per_mil</span> <span class="o">=</span> <span class="mf">0.0254</span>


<div class="viewcode-block" id="to_mils">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.to_mils">[docs]</a>
<span class="nd">@export_to_all</span>
<span class="k">def</span> <span class="nf">to_mils</span><span class="p">(</span><span class="n">mm</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Convert millimeters to thousandths-of-inch (mils).</span>
<span class="sd">    </span>
<span class="sd">    Args:</span>
<span class="sd">        mm (float): Value in millimeters.</span>
<span class="sd">        </span>
<span class="sd">    Returns:</span>
<span class="sd">        float: Equivalent value in mils.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">return</span> <span class="n">mm</span> <span class="o">*</span> <span class="n">mils_per_mm</span></div>



<div class="viewcode-block" id="to_mms">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.to_mms">[docs]</a>
<span class="nd">@export_to_all</span>
<span class="k">def</span> <span class="nf">to_mms</span><span class="p">(</span><span class="n">mils</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    Convert thousandths-of-inch (mils) to millimeters.</span>
<span class="sd">    </span>
<span class="sd">    Args:</span>
<span class="sd">        mils (float): Value in mils.</span>
<span class="sd">        </span>
<span class="sd">    Returns:</span>
<span class="sd">        float: Equivalent value in millimeters.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    <span class="k">return</span> <span class="n">mils</span> <span class="o">*</span> <span class="n">mms_per_mil</span></div>



<div class="viewcode-block" id="Tx">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Tx">[docs]</a>
<span class="nd">@export_to_all</span>
<span class="k">class</span> <span class="nc">Tx</span><span class="p">:</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A 2D transformation matrix for geometric operations.</span>
<span class="sd">    </span>
<span class="sd">    This class implements a 3x3 transformation matrix for 2D operations</span>
<span class="sd">    like rotation, scaling, flipping, and translation. The matrix has</span>
<span class="sd">    the following structure:</span>
<span class="sd">    </span>
<span class="sd">    [ a  b  0 ]</span>
<span class="sd">    [ c  d  0 ]</span>
<span class="sd">    [ dx dy 1 ]</span>
<span class="sd">    </span>
<span class="sd">    Where the transformed coordinates are calculated as:</span>
<span class="sd">    x&#39; = a*x + c*y + dx</span>
<span class="sd">    y&#39; = b*x + d*y + dy</span>
<span class="sd">    </span>
<span class="sd">    Args:</span>
<span class="sd">        a (float, optional): Scaling/rotation factor for x coordinate. Defaults to 1.</span>
<span class="sd">        b (float, optional): Rotation factor for y contribution to x. Defaults to 0.</span>
<span class="sd">        c (float, optional): Rotation factor for x contribution to y. Defaults to 0.</span>
<span class="sd">        d (float, optional): Scaling/rotation factor for y coordinate. Defaults to 1.</span>
<span class="sd">        dx (float, optional): Translation in x direction. Defaults to 0.</span>
<span class="sd">        dy (float, optional): Translation in y direction. Defaults to 0.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">a</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">d</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">dx</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">dy</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Create a transformation matrix.</span>
<span class="sd">        tx = [</span>
<span class="sd">               a  b  0</span>
<span class="sd">               c  d  0</span>
<span class="sd">               dx dy 1</span>
<span class="sd">             ]</span>
<span class="sd">        x&#39; = a*x + c*y + dx</span>
<span class="sd">        y&#39; = b*x + d*y + dy</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">a</span> <span class="o">=</span> <span class="n">a</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">b</span> <span class="o">=</span> <span class="n">b</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">c</span> <span class="o">=</span> <span class="n">c</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">d</span> <span class="o">=</span> <span class="n">d</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">dx</span> <span class="o">=</span> <span class="n">dx</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">dy</span> <span class="o">=</span> <span class="n">dy</span>

<div class="viewcode-block" id="Tx.from_symtx">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Tx.from_symtx">[docs]</a>
    <span class="nd">@classmethod</span>
    <span class="k">def</span> <span class="nf">from_symtx</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">symtx</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Create a transformation matrix from a string of symbolic operations.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            symtx (str): A string of H, V, L, R operations that are applied in sequence left-to-right.</span>
<span class="sd">                        H = horizontal flip, V = vertical flip, </span>
<span class="sd">                        L = rotate 90° left (CCW), R = rotate 90° right (CW)</span>
<span class="sd">                        </span>
<span class="sd">        Returns:</span>
<span class="sd">            Tx: A transformation matrix that implements the sequence of operations.</span>
<span class="sd">            </span>
<span class="sd">        Examples:</span>
<span class="sd">            &gt;&gt;&gt; tx = Tx.from_symtx(&quot;RH&quot;)  # Rotate right, then flip horizontally</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">op_dict</span> <span class="o">=</span> <span class="p">{</span>
            <span class="s2">&quot;H&quot;</span><span class="p">:</span> <span class="n">Tx</span><span class="p">(</span><span class="n">a</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">d</span><span class="o">=</span><span class="mi">1</span><span class="p">),</span>  <span class="c1"># Horizontal flip.</span>
            <span class="s2">&quot;V&quot;</span><span class="p">:</span> <span class="n">Tx</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">d</span><span class="o">=-</span><span class="mi">1</span><span class="p">),</span>  <span class="c1"># Vertical flip.</span>
            <span class="s2">&quot;L&quot;</span><span class="p">:</span> <span class="n">Tx</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">c</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">d</span><span class="o">=</span><span class="mi">0</span><span class="p">),</span>  <span class="c1"># Rotate 90 degrees left (counter-clockwise).</span>
            <span class="s2">&quot;R&quot;</span><span class="p">:</span> <span class="n">Tx</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">b</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span> <span class="n">d</span><span class="o">=</span><span class="mi">0</span><span class="p">),</span>  <span class="c1"># Rotate 90 degrees right (clockwise).</span>
        <span class="p">}</span>

        <span class="n">tx</span> <span class="o">=</span> <span class="n">Tx</span><span class="p">()</span>
        <span class="k">for</span> <span class="n">op</span> <span class="ow">in</span> <span class="n">symtx</span><span class="o">.</span><span class="n">upper</span><span class="p">():</span>
            <span class="n">tx</span> <span class="o">*=</span> <span class="n">op_dict</span><span class="p">[</span><span class="n">op</span><span class="p">]</span>
        <span class="k">return</span> <span class="n">tx</span></div>


    <span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return a string representation of the transformation matrix.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            str: String showing the class name and transformation parameters.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="si">}</span><span class="s2">(</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">a</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">b</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">c</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">d</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">dx</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">dy</span><span class="si">}</span><span class="s2">)&quot;</span>

    <span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return a simplified string representation of the transformation matrix.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            str: String showing the transformation parameters in a list format.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;[</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">a</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">b</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">c</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">d</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">dx</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">dy</span><span class="si">}</span><span class="s2">]&quot;</span>

    <span class="k">def</span> <span class="fm">__mul__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">m</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Multiply this transformation matrix by another matrix or scalar.</span>
<span class="sd">        </span>
<span class="sd">        If m is another transformation matrix, the matrices are multiplied.</span>
<span class="sd">        If m is a scalar, it scales the matrix uniformly.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            m: Another Tx object or a scalar.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            Tx: The resulting transformation matrix.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">Tx</span><span class="p">):</span>
            <span class="n">tx</span> <span class="o">=</span> <span class="n">m</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="c1"># Assume m is a scalar, so convert it to a scaling Tx matrix.</span>
            <span class="n">tx</span> <span class="o">=</span> <span class="n">Tx</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="n">m</span><span class="p">,</span> <span class="n">d</span><span class="o">=</span><span class="n">m</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">Tx</span><span class="p">(</span>
            <span class="n">a</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">a</span> <span class="o">*</span> <span class="n">tx</span><span class="o">.</span><span class="n">a</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">b</span> <span class="o">*</span> <span class="n">tx</span><span class="o">.</span><span class="n">c</span><span class="p">,</span>
            <span class="n">b</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">a</span> <span class="o">*</span> <span class="n">tx</span><span class="o">.</span><span class="n">b</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">b</span> <span class="o">*</span> <span class="n">tx</span><span class="o">.</span><span class="n">d</span><span class="p">,</span>
            <span class="n">c</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">c</span> <span class="o">*</span> <span class="n">tx</span><span class="o">.</span><span class="n">a</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">d</span> <span class="o">*</span> <span class="n">tx</span><span class="o">.</span><span class="n">c</span><span class="p">,</span>
            <span class="n">d</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">c</span> <span class="o">*</span> <span class="n">tx</span><span class="o">.</span><span class="n">b</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">d</span> <span class="o">*</span> <span class="n">tx</span><span class="o">.</span><span class="n">d</span><span class="p">,</span>
            <span class="n">dx</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">dx</span> <span class="o">*</span> <span class="n">tx</span><span class="o">.</span><span class="n">a</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">dy</span> <span class="o">*</span> <span class="n">tx</span><span class="o">.</span><span class="n">c</span> <span class="o">+</span> <span class="n">tx</span><span class="o">.</span><span class="n">dx</span><span class="p">,</span>
            <span class="n">dy</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">dx</span> <span class="o">*</span> <span class="n">tx</span><span class="o">.</span><span class="n">b</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">dy</span> <span class="o">*</span> <span class="n">tx</span><span class="o">.</span><span class="n">d</span> <span class="o">+</span> <span class="n">tx</span><span class="o">.</span><span class="n">dy</span><span class="p">,</span>
        <span class="p">)</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">origin</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Get the translation component of the transformation.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            Point: A Point object representing the (dx, dy) translation.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">Point</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">dx</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">dy</span><span class="p">)</span>

    <span class="c1"># This setter doesn&#39;t work in Python 2.7.18.</span>
    <span class="c1"># @origin.setter</span>
    <span class="c1"># def origin(self, pt):</span>
    <span class="c1">#     &quot;&quot;&quot;Set the (dx, dy) translation from an (x,y) Point.&quot;&quot;&quot;</span>
    <span class="c1">#     self.dx, self.dy = pt.x, pt.y</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">scale</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Get the scaling factor of the transformation.</span>
<span class="sd">        </span>
<span class="sd">        This calculates the length of a unit vector after transformation.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            float: The scaling factor.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="p">(</span><span class="n">Point</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">*</span> <span class="bp">self</span> <span class="o">-</span> <span class="n">Point</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span> <span class="o">*</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">magnitude</span>

<div class="viewcode-block" id="Tx.move">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Tx.move">[docs]</a>
    <span class="k">def</span> <span class="nf">move</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">vec</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return a new Tx with an additional translation applied.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            vec (Point): The vector to translate by.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            Tx: A new transformation matrix with the translation applied.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="bp">self</span> <span class="o">*</span> <span class="n">Tx</span><span class="p">(</span><span class="n">dx</span><span class="o">=</span><span class="n">vec</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">dy</span><span class="o">=</span><span class="n">vec</span><span class="o">.</span><span class="n">y</span><span class="p">)</span></div>


<div class="viewcode-block" id="Tx.rot_90cw">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Tx.rot_90cw">[docs]</a>
    <span class="k">def</span> <span class="nf">rot_90cw</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return a new Tx with a 90-degree clockwise rotation applied.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            Tx: A new transformation matrix with the rotation applied.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="bp">self</span> <span class="o">*</span> <span class="n">Tx</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">c</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span> <span class="n">d</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span></div>


<div class="viewcode-block" id="Tx.rot">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Tx.rot">[docs]</a>
    <span class="k">def</span> <span class="nf">rot</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">degs</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return a new Tx with a rotation by the given angle in degrees.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            degs (float): The rotation angle in degrees.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            Tx: A new transformation matrix with the rotation applied.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">rads</span> <span class="o">=</span> <span class="n">radians</span><span class="p">(</span><span class="n">degs</span><span class="p">)</span>
        <span class="k">return</span> <span class="bp">self</span> <span class="o">*</span> <span class="n">Tx</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="n">cos</span><span class="p">(</span><span class="n">rads</span><span class="p">),</span> <span class="n">b</span><span class="o">=</span><span class="n">sin</span><span class="p">(</span><span class="n">rads</span><span class="p">),</span> <span class="n">c</span><span class="o">=-</span><span class="n">sin</span><span class="p">(</span><span class="n">rads</span><span class="p">),</span> <span class="n">d</span><span class="o">=</span><span class="n">cos</span><span class="p">(</span><span class="n">rads</span><span class="p">))</span></div>


<div class="viewcode-block" id="Tx.flip_x">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Tx.flip_x">[docs]</a>
    <span class="k">def</span> <span class="nf">flip_x</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return a new Tx with a horizontal flip (mirror across y-axis).</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            Tx: A new transformation matrix with the flip applied.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="bp">self</span> <span class="o">*</span> <span class="n">Tx</span><span class="p">(</span><span class="n">a</span><span class="o">=-</span><span class="mi">1</span><span class="p">)</span></div>


<div class="viewcode-block" id="Tx.flip_y">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Tx.flip_y">[docs]</a>
    <span class="k">def</span> <span class="nf">flip_y</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return a new Tx with a vertical flip (mirror across x-axis).</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            Tx: A new transformation matrix with the flip applied.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="bp">self</span> <span class="o">*</span> <span class="n">Tx</span><span class="p">(</span><span class="n">d</span><span class="o">=-</span><span class="mi">1</span><span class="p">)</span></div>


<div class="viewcode-block" id="Tx.no_translate">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Tx.no_translate">[docs]</a>
    <span class="k">def</span> <span class="nf">no_translate</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return a new Tx with the same rotation/scaling but no translation.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            Tx: A new transformation matrix with translation set to (0,0).</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">Tx</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">c</span><span class="p">,</span> <span class="n">d</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">d</span><span class="p">)</span></div>
</div>



<span class="c1"># Some common rotations.</span>
<span class="n">tx_rot_0</span> <span class="o">=</span> <span class="n">Tx</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">d</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="n">tx_rot_90</span> <span class="o">=</span> <span class="n">Tx</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">c</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span> <span class="n">d</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>
<span class="n">tx_rot_180</span> <span class="o">=</span> <span class="n">Tx</span><span class="p">(</span><span class="n">a</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">d</span><span class="o">=-</span><span class="mi">1</span><span class="p">)</span>
<span class="n">tx_rot_270</span> <span class="o">=</span> <span class="n">Tx</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">b</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">d</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span>

<span class="c1"># Some common flips.</span>
<span class="n">tx_flip_x</span> <span class="o">=</span> <span class="n">Tx</span><span class="p">(</span><span class="n">a</span><span class="o">=-</span><span class="mi">1</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">d</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="n">tx_flip_y</span> <span class="o">=</span> <span class="n">Tx</span><span class="p">(</span><span class="n">a</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">b</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">c</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">d</span><span class="o">=-</span><span class="mi">1</span><span class="p">)</span>


<div class="viewcode-block" id="Point">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Point">[docs]</a>
<span class="nd">@export_to_all</span>
<span class="k">class</span> <span class="nc">Point</span><span class="p">:</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A 2D point or vector with x and y coordinates.</span>
<span class="sd">    </span>
<span class="sd">    The Point class represents both points in space and vectors for</span>
<span class="sd">    geometric operations. It supports various arithmetic operations</span>
<span class="sd">    and can be transformed using the Tx transformation matrix.</span>
<span class="sd">    </span>
<span class="sd">    Args:</span>
<span class="sd">        x (float): The x-coordinate.</span>
<span class="sd">        y (float): The y-coordinate.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Create a Point with coords x,y.&quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">=</span> <span class="n">x</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">=</span> <span class="n">y</span>

    <span class="k">def</span> <span class="fm">__hash__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Generate a hash value for the point.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            int: Hash value based on the x and y coordinates.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="nb">hash</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">))</span>

    <span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Check if two points have the same coordinates.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            other (Point): Another point to compare with.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            bool: True if both points have the same coordinates.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">)</span> <span class="o">==</span> <span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>

    <span class="k">def</span> <span class="fm">__lt__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Compare points lexicographically (first by x, then by y).</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            other (Point): Another point to compare with.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            bool: True if self is less than other.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">)</span> <span class="o">&lt;</span> <span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>

    <span class="k">def</span> <span class="fm">__ne__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Check if two points have different coordinates.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            other (Point): Another point to compare with.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            bool: True if points have different coordinates.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="ow">not</span> <span class="p">(</span><span class="bp">self</span> <span class="o">==</span> <span class="n">other</span><span class="p">)</span>

    <span class="k">def</span> <span class="fm">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pt</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Add another point or scalar to this point.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            pt (Point or number): Point or scalar to add.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            Point: A new point with the sum of coordinates.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">pt</span><span class="p">,</span> <span class="n">Point</span><span class="p">):</span>
            <span class="n">pt</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="n">pt</span><span class="p">,</span> <span class="n">pt</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">Point</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">+</span> <span class="n">pt</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">+</span> <span class="n">pt</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>

    <span class="k">def</span> <span class="fm">__sub__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pt</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Subtract another point or scalar from this point.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            pt (Point or number): Point or scalar to subtract.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            Point: A new point with the difference of coordinates.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">pt</span><span class="p">,</span> <span class="n">Point</span><span class="p">):</span>
            <span class="n">pt</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="n">pt</span><span class="p">,</span> <span class="n">pt</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">Point</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">-</span> <span class="n">pt</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">-</span> <span class="n">pt</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>

    <span class="k">def</span> <span class="fm">__mul__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">m</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Multiply this point by a transformation, another point, or a scalar.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            m: A Tx transformation, another Point (for component-wise multiplication),</span>
<span class="sd">               or a scalar.</span>
<span class="sd">               </span>
<span class="sd">        Returns:</span>
<span class="sd">            Point: The transformed/scaled point.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">Tx</span><span class="p">):</span>
            <span class="k">return</span> <span class="n">Point</span><span class="p">(</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">*</span> <span class="n">m</span><span class="o">.</span><span class="n">a</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">*</span> <span class="n">m</span><span class="o">.</span><span class="n">c</span> <span class="o">+</span> <span class="n">m</span><span class="o">.</span><span class="n">dx</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">*</span> <span class="n">m</span><span class="o">.</span><span class="n">b</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">*</span> <span class="n">m</span><span class="o">.</span><span class="n">d</span> <span class="o">+</span> <span class="n">m</span><span class="o">.</span><span class="n">dy</span>
            <span class="p">)</span>
        <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">Point</span><span class="p">):</span>
            <span class="k">return</span> <span class="n">Point</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">*</span> <span class="n">m</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">*</span> <span class="n">m</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">Point</span><span class="p">(</span><span class="n">m</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">m</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>

    <span class="k">def</span> <span class="fm">__rmul__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">m</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Right multiplication with a scalar.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            m: A scalar value.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            Point: Scaled point.</span>
<span class="sd">            </span>
<span class="sd">        Raises:</span>
<span class="sd">            ValueError: If m is a Tx transformation matrix.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">Tx</span><span class="p">):</span>
            <span class="k">raise</span> <span class="ne">ValueError</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">return</span> <span class="bp">self</span> <span class="o">*</span> <span class="n">m</span>

<div class="viewcode-block" id="Point.xprod">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Point.xprod">[docs]</a>
    <span class="k">def</span> <span class="nf">xprod</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pt</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Calculate the cross product of this vector and another.</span>
<span class="sd">        </span>
<span class="sd">        For 2D vectors, the cross product returns a scalar representing</span>
<span class="sd">        the z-component of the 3D cross product.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            pt (Point): Another point/vector.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            float: The cross product value.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">*</span> <span class="n">pt</span><span class="o">.</span><span class="n">y</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">*</span> <span class="n">pt</span><span class="o">.</span><span class="n">x</span></div>


<div class="viewcode-block" id="Point.mask">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Point.mask">[docs]</a>
    <span class="k">def</span> <span class="nf">mask</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">msk</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Apply a binary mask to the coordinates.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            msk (list or tuple): A pair of values to multiply with x and y.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            Point: New point with masked coordinates.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">Point</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">*</span> <span class="n">msk</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">*</span> <span class="n">msk</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span></div>


    <span class="k">def</span> <span class="fm">__neg__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Negate both coordinates.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            Point: A new point with negated coordinates.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">Point</span><span class="p">(</span><span class="o">-</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="o">-</span><span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>

    <span class="k">def</span> <span class="fm">__truediv__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">d</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Divide coordinates by a scalar.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            d (number): Divisor.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            Point: New point with divided coordinates.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">Point</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">/</span> <span class="n">d</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">/</span> <span class="n">d</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">__div__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">d</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Divide coordinates by a scalar (Python 2 compatibility).</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            d (number): Divisor.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            Point: New point with divided coordinates.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">Point</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">/</span> <span class="n">d</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">/</span> <span class="n">d</span><span class="p">)</span>

<div class="viewcode-block" id="Point.round">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Point.round">[docs]</a>
    <span class="k">def</span> <span class="nf">round</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Round coordinates to nearest integers.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            Point: New point with rounded coordinates.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">Point</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="nb">round</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">)),</span> <span class="nb">int</span><span class="p">(</span><span class="nb">round</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">)))</span></div>


    <span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Convert point to a space-separated string representation.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            str: String with x and y coordinates.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="si">}</span><span class="s2">&quot;</span>

<div class="viewcode-block" id="Point.snap">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Point.snap">[docs]</a>
    <span class="k">def</span> <span class="nf">snap</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">grid_spacing</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Snap point coordinates to a grid.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            grid_spacing (float): Grid interval to snap to.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            Point: New point with coordinates snapped to the grid.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">snap_func</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="nb">int</span><span class="p">(</span><span class="n">grid_spacing</span> <span class="o">*</span> <span class="nb">round</span><span class="p">(</span><span class="n">x</span> <span class="o">/</span> <span class="n">grid_spacing</span><span class="p">))</span>
        <span class="k">return</span> <span class="n">Point</span><span class="p">(</span><span class="n">snap_func</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">),</span> <span class="n">snap_func</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">))</span></div>


<div class="viewcode-block" id="Point.min">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Point.min">[docs]</a>
    <span class="k">def</span> <span class="nf">min</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pt</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Create a new point using the minimum x and y from two points.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            pt (Point): Another point to compare with.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            Point: New point with minimum x and y values.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">Point</span><span class="p">(</span><span class="nb">min</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">pt</span><span class="o">.</span><span class="n">x</span><span class="p">),</span> <span class="nb">min</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="n">pt</span><span class="o">.</span><span class="n">y</span><span class="p">))</span></div>


<div class="viewcode-block" id="Point.max">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Point.max">[docs]</a>
    <span class="k">def</span> <span class="nf">max</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pt</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Create a new point using the maximum x and y from two points.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            pt (Point): Another point to compare with.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            Point: New point with maximum x and y values.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">Point</span><span class="p">(</span><span class="nb">max</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">pt</span><span class="o">.</span><span class="n">x</span><span class="p">),</span> <span class="nb">max</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="n">pt</span><span class="o">.</span><span class="n">y</span><span class="p">))</span></div>


    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">magnitude</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Calculate the distance of the point from origin (vector length).</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            float: The Euclidean distance from origin.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">sqrt</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="o">**</span><span class="mi">2</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="o">**</span><span class="mi">2</span><span class="p">)</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">norm</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Calculate a unit vector in the same direction.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            Point: Normalized vector with length 1, or (0,0) if zero length.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="k">return</span> <span class="bp">self</span> <span class="o">/</span> <span class="bp">self</span><span class="o">.</span><span class="n">magnitude</span>
        <span class="k">except</span> <span class="ne">ZeroDivisionError</span><span class="p">:</span>
            <span class="k">return</span> <span class="n">Point</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>

<div class="viewcode-block" id="Point.flip_xy">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Point.flip_xy">[docs]</a>
    <span class="k">def</span> <span class="nf">flip_xy</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Swap the x and y coordinates in place.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">x</span></div>


    <span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return a string representation for debugging.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            str: String with class name and x,y coordinates.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="si">}</span><span class="s2">(</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">x</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">y</span><span class="si">}</span><span class="s2">)&quot;</span></div>



<span class="n">Vector</span> <span class="o">=</span> <span class="n">Point</span>


<div class="viewcode-block" id="BBox">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.BBox">[docs]</a>
<span class="nd">@export_to_all</span>
<span class="k">class</span> <span class="nc">BBox</span><span class="p">:</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A bounding box defined by minimum and maximum points.</span>
<span class="sd">    </span>
<span class="sd">    BBox represents a rectangular area that can contain points or other bounding boxes.</span>
<span class="sd">    It provides methods for combining bounding boxes, testing if points are inside,</span>
<span class="sd">    and calculating intersections.</span>
<span class="sd">    </span>
<span class="sd">    Args:</span>
<span class="sd">        *pts: One or more Point objects defining the initial bounding box.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">pts</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Create a bounding box surrounding the given points.&quot;&quot;&quot;</span>
        <span class="n">inf</span> <span class="o">=</span> <span class="nb">float</span><span class="p">(</span><span class="s2">&quot;inf&quot;</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">min</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="n">inf</span><span class="p">,</span> <span class="n">inf</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">max</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="o">-</span><span class="n">inf</span><span class="p">,</span> <span class="o">-</span><span class="n">inf</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="o">*</span><span class="n">pts</span><span class="p">)</span>

    <span class="k">def</span> <span class="fm">__add__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Merge this bounding box with a point or another bounding box.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            obj (Point or BBox): Object to merge with.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            BBox: A new bounding box that contains both this bbox and the object.</span>
<span class="sd">            </span>
<span class="sd">        Raises:</span>
<span class="sd">            NotImplementedError: If obj is not a Point or BBox.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">sum_</span> <span class="o">=</span> <span class="n">BBox</span><span class="p">()</span>
        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">Point</span><span class="p">):</span>
            <span class="n">sum_</span><span class="o">.</span><span class="n">min</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="o">.</span><span class="n">min</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
            <span class="n">sum_</span><span class="o">.</span><span class="n">max</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="o">.</span><span class="n">max</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
        <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">BBox</span><span class="p">):</span>
            <span class="n">sum_</span><span class="o">.</span><span class="n">min</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="o">.</span><span class="n">min</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">min</span><span class="p">)</span>
            <span class="n">sum_</span><span class="o">.</span><span class="n">max</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="o">.</span><span class="n">max</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">max</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">NotImplementedError</span>
        <span class="k">return</span> <span class="n">sum_</span>

    <span class="k">def</span> <span class="fm">__iadd__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Expand this bounding box to include a point or another bounding box.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            obj (Point or BBox): Object to include in this bbox.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            BBox: The updated bounding box (self).</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">sum_</span> <span class="o">=</span> <span class="bp">self</span> <span class="o">+</span> <span class="n">obj</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">min</span> <span class="o">=</span> <span class="n">sum_</span><span class="o">.</span><span class="n">min</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">max</span> <span class="o">=</span> <span class="n">sum_</span><span class="o">.</span><span class="n">max</span>
        <span class="k">return</span> <span class="bp">self</span>

<div class="viewcode-block" id="BBox.add">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.BBox.add">[docs]</a>
    <span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="n">objs</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Update the bounding box to include multiple points and/or bounding boxes.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            *objs: Points or BBoxes to include in this bounding box.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            BBox: The updated bounding box (self).</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">objs</span><span class="p">:</span>
            <span class="bp">self</span> <span class="o">+=</span> <span class="n">obj</span>
        <span class="k">return</span> <span class="bp">self</span></div>


    <span class="k">def</span> <span class="fm">__mul__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">m</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Apply a transformation to this bounding box.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            m (Tx): Transformation matrix to apply.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            BBox: A new transformed bounding box.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">BBox</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">min</span> <span class="o">*</span> <span class="n">m</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span> <span class="o">*</span> <span class="n">m</span><span class="p">)</span>

<div class="viewcode-block" id="BBox.round">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.BBox.round">[docs]</a>
    <span class="k">def</span> <span class="nf">round</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Round the bounding box limits to integers.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            BBox: A new bounding box with rounded coordinates.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">BBox</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="o">.</span><span class="n">round</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="o">.</span><span class="n">round</span><span class="p">())</span></div>


<div class="viewcode-block" id="BBox.is_inside">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.BBox.is_inside">[docs]</a>
    <span class="k">def</span> <span class="nf">is_inside</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">pt</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Check if a point is inside or on the boundary of this bounding box.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            pt (Point): The point to check.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            bool: True if the point is inside or on the boundary.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="o">.</span><span class="n">x</span> <span class="o">&lt;=</span> <span class="n">pt</span><span class="o">.</span><span class="n">x</span> <span class="o">&lt;=</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="o">.</span><span class="n">x</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="o">.</span><span class="n">y</span> <span class="o">&lt;=</span> <span class="n">pt</span><span class="o">.</span><span class="n">y</span> <span class="o">&lt;=</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="o">.</span><span class="n">y</span><span class="p">)</span></div>


<div class="viewcode-block" id="BBox.intersects">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.BBox.intersects">[docs]</a>
    <span class="k">def</span> <span class="nf">intersects</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bbox</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Check if this bounding box intersects with another.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            bbox (BBox): Another bounding box to check for intersection.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            bool: True if the bounding boxes intersect.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="p">(</span>
            <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="o">.</span><span class="n">x</span> <span class="o">&lt;</span> <span class="n">bbox</span><span class="o">.</span><span class="n">max</span><span class="o">.</span><span class="n">x</span><span class="p">)</span>
            <span class="ow">and</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="o">.</span><span class="n">x</span> <span class="o">&gt;</span> <span class="n">bbox</span><span class="o">.</span><span class="n">min</span><span class="o">.</span><span class="n">x</span><span class="p">)</span>
            <span class="ow">and</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="o">.</span><span class="n">y</span> <span class="o">&lt;</span> <span class="n">bbox</span><span class="o">.</span><span class="n">max</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>
            <span class="ow">and</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="o">.</span><span class="n">y</span> <span class="o">&gt;</span> <span class="n">bbox</span><span class="o">.</span><span class="n">min</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>
        <span class="p">)</span></div>


<div class="viewcode-block" id="BBox.intersection">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.BBox.intersection">[docs]</a>
    <span class="k">def</span> <span class="nf">intersection</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bbox</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Calculate the intersection of this bounding box with another.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            bbox (BBox): Another bounding box.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            BBox or None: A new bounding box representing the intersection,</span>
<span class="sd">                         or None if there is no intersection.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">intersects</span><span class="p">(</span><span class="n">bbox</span><span class="p">):</span>
            <span class="k">return</span> <span class="kc">None</span>
        <span class="n">corner1</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="o">.</span><span class="n">max</span><span class="p">(</span><span class="n">bbox</span><span class="o">.</span><span class="n">min</span><span class="p">)</span>
        <span class="n">corner2</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="o">.</span><span class="n">min</span><span class="p">(</span><span class="n">bbox</span><span class="o">.</span><span class="n">max</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">BBox</span><span class="p">(</span><span class="n">corner1</span><span class="p">,</span> <span class="n">corner2</span><span class="p">)</span></div>


<div class="viewcode-block" id="BBox.resize">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.BBox.resize">[docs]</a>
    <span class="k">def</span> <span class="nf">resize</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">vector</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Expand or contract the bounding box by a given amount in all directions.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            vector (Point): Amount to expand by (positive values) or contract by </span>
<span class="sd">                          (negative values) in x and y directions.</span>
<span class="sd">                          </span>
<span class="sd">        Returns:</span>
<span class="sd">            BBox: A new resized bounding box.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">BBox</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">min</span> <span class="o">-</span> <span class="n">vector</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span> <span class="o">+</span> <span class="n">vector</span><span class="p">)</span></div>


<div class="viewcode-block" id="BBox.snap_resize">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.BBox.snap_resize">[docs]</a>
    <span class="k">def</span> <span class="nf">snap_resize</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">grid_spacing</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Resize the bounding box to align min and max points to a grid.</span>
<span class="sd">        </span>
<span class="sd">        This expands the bounding box outward so that its corners align with</span>
<span class="sd">        the given grid spacing.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            grid_spacing (float): Grid spacing to align to.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            BBox: A new bounding box with grid-aligned corners.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">bbox</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">resize</span><span class="p">(</span><span class="n">Point</span><span class="p">(</span><span class="n">grid_spacing</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">grid_spacing</span> <span class="o">-</span> <span class="mi">1</span><span class="p">))</span>
        <span class="n">bbox</span><span class="o">.</span><span class="n">min</span> <span class="o">=</span> <span class="n">bbox</span><span class="o">.</span><span class="n">min</span><span class="o">.</span><span class="n">snap</span><span class="p">(</span><span class="n">grid_spacing</span><span class="p">)</span>
        <span class="n">bbox</span><span class="o">.</span><span class="n">max</span> <span class="o">=</span> <span class="n">bbox</span><span class="o">.</span><span class="n">max</span><span class="o">.</span><span class="n">snap</span><span class="p">(</span><span class="n">grid_spacing</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">bbox</span></div>


    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">area</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Calculate the area of the bounding box.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            float: Area (width × height).</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">w</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">h</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">w</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Return the bounding box width.&quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="nb">abs</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="o">.</span><span class="n">x</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="o">.</span><span class="n">x</span><span class="p">)</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">h</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Get the height of the bounding box.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            float: Height of the bounding box.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="nb">abs</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="o">.</span><span class="n">y</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">ctr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Get the center point of the bounding box.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            Point: Center point.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">ll</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Get the lower-left corner of the bounding box.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            Point: Lower-left corner point.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">Point</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">lr</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Get the lower-right corner of the bounding box.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            Point: Lower-right corner point.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">Point</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">ul</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Get the upper-left corner of the bounding box.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            Point: Upper-left corner point.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">Point</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">ur</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Get the upper-right corner of the bounding box.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            Point: Upper-right corner point.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">Point</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>

    <span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return a string representation for debugging.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            str: String showing the class name and min/max points.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="nb">type</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="si">}</span><span class="s2">(Point(</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="si">}</span><span class="s2">), Point(</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="si">}</span><span class="s2">))&quot;</span>

    <span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return a simplified string representation.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            str: String representation of the min/max points.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;[</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">min</span><span class="si">}</span><span class="s2">, </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">max</span><span class="si">}</span><span class="s2">]&quot;</span></div>



<div class="viewcode-block" id="Segment">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Segment">[docs]</a>
<span class="nd">@export_to_all</span>
<span class="k">class</span> <span class="nc">Segment</span><span class="p">:</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">    A line segment between two points.</span>
<span class="sd">    </span>
<span class="sd">    Represents a straight line segment with endpoints p1 and p2.</span>
<span class="sd">    </span>
<span class="sd">    Args:</span>
<span class="sd">        p1 (Point): First endpoint.</span>
<span class="sd">        p2 (Point): Second endpoint.</span>
<span class="sd">    &quot;&quot;&quot;</span>
    
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">p1</span><span class="p">,</span> <span class="n">p2</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Create a line segment between two points.&quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">p1</span> <span class="o">=</span> <span class="n">copy</span><span class="p">(</span><span class="n">p1</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">p2</span> <span class="o">=</span> <span class="n">copy</span><span class="p">(</span><span class="n">p2</span><span class="p">)</span>

    <span class="k">def</span> <span class="fm">__mul__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">m</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Apply a transformation to the segment.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            m (Tx): Transformation matrix to apply.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            Segment: A new transformed segment.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">Segment</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">p1</span> <span class="o">*</span> <span class="n">m</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">p2</span> <span class="o">*</span> <span class="n">m</span><span class="p">)</span>

<div class="viewcode-block" id="Segment.round">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Segment.round">[docs]</a>
    <span class="k">def</span> <span class="nf">round</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Round the segment endpoints to integers.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            Segment: A new segment with rounded endpoint coordinates.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="n">Segment</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">p1</span><span class="o">.</span><span class="n">round</span><span class="p">(),</span> <span class="bp">self</span><span class="o">.</span><span class="n">p2</span><span class="o">.</span><span class="n">round</span><span class="p">())</span></div>


    <span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Return a string representation of the segment.</span>
<span class="sd">        </span>
<span class="sd">        Returns:</span>
<span class="sd">            str: String with the segment endpoints.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">p1</span><span class="p">)</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">p2</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span>

<div class="viewcode-block" id="Segment.flip_xy">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Segment.flip_xy">[docs]</a>
    <span class="k">def</span> <span class="nf">flip_xy</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Swap the x and y coordinates of both endpoints.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">p1</span><span class="o">.</span><span class="n">flip_xy</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">p2</span><span class="o">.</span><span class="n">flip_xy</span><span class="p">()</span></div>


<div class="viewcode-block" id="Segment.intersects">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Segment.intersects">[docs]</a>
    <span class="k">def</span> <span class="nf">intersects</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Check if this segment intersects with another segment.</span>
<span class="sd">        </span>
<span class="sd">        Note: This method is not fully implemented and will raise an error.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            other (Segment): Another segment to check for intersection.</span>
<span class="sd">            </span>
<span class="sd">        Raises:</span>
<span class="sd">            NotImplementedError: This method is not fully implemented.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="c1"># FIXME: This fails if the segments are parallel!</span>
        <span class="k">raise</span> <span class="ne">NotImplementedError</span>

        <span class="c1"># Given two segments:</span>
        <span class="c1">#   self: p1 + (p2-p1) * t1</span>
        <span class="c1">#   other: p3 + (p4-p3) * t2</span>
        <span class="c1"># Look for a solution t1, t2 that solves:</span>
        <span class="c1">#   p1x + (p2x-p1x)*t1 = p3x + (p4x-p3x)*t2</span>
        <span class="c1">#   p1y + (p2y-p1y)*t1 = p3y + (p4y-p3y)*t2</span>
        <span class="c1"># If t1 and t2 are both in range [0,1], then the two segments intersect.</span>

        <span class="n">p1x</span><span class="p">,</span> <span class="n">p1y</span><span class="p">,</span> <span class="n">p2x</span><span class="p">,</span> <span class="n">p2y</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">p1</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">p1</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">p2</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">p2</span><span class="o">.</span><span class="n">y</span>
        <span class="n">p3x</span><span class="p">,</span> <span class="n">p3y</span><span class="p">,</span> <span class="n">p4x</span><span class="p">,</span> <span class="n">p4y</span> <span class="o">=</span> <span class="n">other</span><span class="o">.</span><span class="n">p1</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">p1</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">p2</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">p2</span><span class="o">.</span><span class="n">y</span>

        <span class="c1"># denom = p1x*p3y - p1x*p4y - p1y*p3x + p1y*p4x - p2x*p3y + p2x*p4y + p2y*p3x - p2y*p4x</span>
        <span class="c1"># denom = p1x * (p3y - p4y) + p1y * (p4x - p3x) + p2x * (p4y - p3y) + p2y * (p3x - p4x)</span>
        <span class="n">denom</span> <span class="o">=</span> <span class="p">(</span><span class="n">p1x</span> <span class="o">-</span> <span class="n">p2x</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">p3y</span> <span class="o">-</span> <span class="n">p4y</span><span class="p">)</span> <span class="o">+</span> <span class="p">(</span><span class="n">p1y</span> <span class="o">-</span> <span class="n">p2y</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">p4x</span> <span class="o">-</span> <span class="n">p3x</span><span class="p">)</span>

        <span class="k">try</span><span class="p">:</span>
            <span class="c1"># t1 = (p1x*p3y - p1x*p4y - p1y*p3x + p1y*p4x + p3x*p4y - p3y*p4x) / denom</span>
            <span class="c1"># t2 = (-p1x*p2y + p1x*p3y + p1y*p2x - p1y*p3x - p2x*p3y + p2y*p3x) / denom</span>
            <span class="n">t1</span> <span class="o">=</span> <span class="p">((</span><span class="n">p1y</span> <span class="o">-</span> <span class="n">p3y</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">p4x</span> <span class="o">-</span> <span class="n">p3x</span><span class="p">)</span> <span class="o">-</span> <span class="p">(</span><span class="n">p1x</span> <span class="o">-</span> <span class="n">p3x</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">p4y</span> <span class="o">-</span> <span class="n">p3y</span><span class="p">))</span> <span class="o">/</span> <span class="n">denom</span>
            <span class="n">t2</span> <span class="o">=</span> <span class="p">((</span><span class="n">p1y</span> <span class="o">-</span> <span class="n">p3y</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">p2x</span> <span class="o">-</span> <span class="n">p3x</span><span class="p">)</span> <span class="o">-</span> <span class="p">(</span><span class="n">p1x</span> <span class="o">-</span> <span class="n">p3x</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">p2y</span> <span class="o">-</span> <span class="n">p3y</span><span class="p">))</span> <span class="o">/</span> <span class="n">denom</span>
        <span class="k">except</span> <span class="ne">ZeroDivisionError</span><span class="p">:</span>
            <span class="k">return</span> <span class="kc">False</span>

        <span class="k">return</span> <span class="p">(</span><span class="mi">0</span> <span class="o">&lt;=</span> <span class="n">t1</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span><span class="mi">0</span> <span class="o">&lt;=</span> <span class="n">t2</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">)</span></div>


<div class="viewcode-block" id="Segment.shadows">
<a class="viewcode-back" href="../../rst_output/skidl.geometry.html#skidl.geometry.Segment.shadows">[docs]</a>
    <span class="k">def</span> <span class="nf">shadows</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Check if two segments overlap when projected onto axes.</span>
<span class="sd">        </span>
<span class="sd">        This tests if the segments would overlap when viewed from above or the side,</span>
<span class="sd">        even if they don&#39;t physically intersect.</span>
<span class="sd">        </span>
<span class="sd">        Args:</span>
<span class="sd">            other (Segment): Another segment to check.</span>
<span class="sd">            </span>
<span class="sd">        Returns:</span>
<span class="sd">            bool: True if segments shadow (overlap) each other on x or y axis.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">p1</span><span class="o">.</span><span class="n">x</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">p2</span><span class="o">.</span><span class="n">x</span> <span class="ow">and</span> <span class="n">other</span><span class="o">.</span><span class="n">p1</span><span class="o">.</span><span class="n">x</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">p2</span><span class="o">.</span><span class="n">x</span><span class="p">:</span>
            <span class="c1"># Horizontal segments. See if their vertical extents overlap.</span>
            <span class="n">self_min</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">p1</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">p2</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>
            <span class="n">self_max</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">p1</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">p2</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>
            <span class="n">other_min</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">p1</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">p2</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>
            <span class="n">other_max</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">p1</span><span class="o">.</span><span class="n">y</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">p2</span><span class="o">.</span><span class="n">y</span><span class="p">)</span>
        <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">p1</span><span class="o">.</span><span class="n">y</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">p2</span><span class="o">.</span><span class="n">y</span> <span class="ow">and</span> <span class="n">other</span><span class="o">.</span><span class="n">p1</span><span class="o">.</span><span class="n">y</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">p2</span><span class="o">.</span><span class="n">y</span><span class="p">:</span>
            <span class="c1"># Verttical segments. See if their horizontal extents overlap.</span>
            <span class="n">self_min</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">p1</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">p2</span><span class="o">.</span><span class="n">x</span><span class="p">)</span>
            <span class="n">self_max</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">p1</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">p2</span><span class="o">.</span><span class="n">x</span><span class="p">)</span>
            <span class="n">other_min</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">p1</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">p2</span><span class="o">.</span><span class="n">x</span><span class="p">)</span>
            <span class="n">other_max</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="n">other</span><span class="o">.</span><span class="n">p1</span><span class="o">.</span><span class="n">x</span><span class="p">,</span> <span class="n">other</span><span class="o">.</span><span class="n">p2</span><span class="o">.</span><span class="n">x</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="c1"># Segments aren&#39;t horizontal or vertical, so neither can shadow the other.</span>
            <span class="k">return</span> <span class="kc">False</span>

        <span class="c1"># Overlap conditions based on segment endpoints.</span>
        <span class="k">return</span> <span class="n">other_min</span> <span class="o">&lt;</span> <span class="n">self_max</span> <span class="ow">and</span> <span class="n">other_max</span> <span class="o">&gt;</span> <span class="n">self_min</span></div>
</div>

</pre></div>

            <div class="clearer"></div>
          </div>
        </div>
      </div>
      <div class="sphinxsidebar" role="navigation" aria-label="Main">
        <div class="sphinxsidebarwrapper">
<search id="searchbox" style="display: none" role="search">
  <h3 id="searchlabel">Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="../../search.html" method="get">
      <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
      <input type="submit" value="Go" />
    </form>
    </div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related" role="navigation" aria-label="Related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="../../genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="../../py-modindex.html" title="Python Module Index"
             >modules</a> |</li>
        <li class="nav-item nav-item-0"><a href="../../index.html">SKiDL 2.2.0 documentation</a> &#187;</li>
          <li class="nav-item nav-item-1"><a href="../index.html" >Module code</a> &#187;</li>
        <li class="nav-item nav-item-this"><a href="">skidl.geometry</a></li> 
      </ul>
    </div>
    <div class="footer" role="contentinfo">
    &#169; Copyright 2016-2025, Dave Vandenbout.
      Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 8.2.3.
    </div>
  </body>
</html>